using System;
using System.Collections;
using System.Data.SqlClient;
using System.Text;
using System.Text.RegularExpressions;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.Policy;
using PHSRAG.Utility;

namespace PHSRAG.Insight21.COI
{
    public partial class AddNote : BasePage
    {
        #region Private instance variables

        private int coiId;
        private Hashtable pageCache;

        #region CachePolicy Variables

        private ICachePolicy cachePolicy;
        private bool canAdd = true;
        private ICachePolicy pageCachePolicy;

        #endregion

        #endregion

        #region Private Constants

        private const string AnnunciatorTitle = "The following error(s) occurred...";
        private const string CanAddNoteKey = "CanAddNoteKey_B176D37D-8A48-4a1f-B0D5-086D8AF1238A";
        private const string PageCacheKey = "AddNotesKey_E3CFFB18-EF51-472f-A8E0-05637C2D31AE";

        #endregion

        #region Protected Page Events

        /// <summary>
        /// Initializes the page and sets up the caching policies
        /// </summary>
        /// <param name="e">arguments from the event</param>
        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);

            #region Initialize the cachepolicy variables

            cachePolicy = (ICachePolicy) Session[Names.CachePolicyKey];
            pageCachePolicy = (ICachePolicy) Session[Names.PageCachePolicyKey];

            #endregion
        }

        /// <summary>
        /// Loads the respective page controls 
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e"> Event arguments</param>        
        protected void OnPageLoad(object sender, EventArgs e)
        {
            try
            {
                LoadReviewNote();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// This event will open the existing COI review note for the selected COI as RTF document.
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e"> Event arguments</param>  
        protected void OnViewNote(object sender, EventArgs e)
        {
            try
            {
                pageCache = pageCachePolicy.GetCachedObject(PageCacheKey) as Hashtable;
                if (pageCache != null)
                {
                    coiId = Convert.ToInt32(pageCache[Keys.COIIdKey]);
                    string reviewNote = string.Empty;
                    SqlDataReader reviewNoteRdr = COIUserSummary.GetCOIReviewNote(coiId, DataAccess.ConnectionString);
                    if (reviewNoteRdr != null && reviewNoteRdr.HasRows)
                    {
                        reviewNoteRdr.Read();
                        reviewNote = reviewNoteRdr["ReviewNote"].ToString();
                        reviewNoteRdr.Close();
                    }
                    if (reviewNote != string.Empty)
                    {
                        OpenReviewNoteAsRTF(reviewNote);
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Event to display the text editor to add a note.
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e"> Event arguments</param> 
        protected void OnAddNewNote(object sender, EventArgs e)
        {
            COINote.Visible = existingNote.Visible = annunciator.Visible = addNewNote.Visible = false;
            addNote.Visible = saveNote.Visible = newNote.Visible = true;
        }

        /// <summary>
        /// Saves the new review note added by the user, stripping of the html tags(which otherwise shows up the html tags in the output).
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e"> Event arguments</param> 
        protected void OnSaveNote(object sender, EventArgs e)
        {
            try
            {
                pageCache = pageCachePolicy.GetCachedObject(PageCacheKey) as Hashtable;
                if (pageCache != null)
                {
                    UserContext userContext = (UserContext) cachePolicy.GetCachedObject(UserContext.CacheKey);
                    if (userContext == null)
                    {
                        throw new Exception("user context unavailable. Please logout & login again");
                    }
                    coiId = Convert.ToInt32(pageCache[Keys.COIIdKey]);
                    string notesWithoutHtml = Regex.Replace(addNote.Text.Trim(), @"<(.|\n)*?>", string.Empty);
                    string notesWithoutHtmltrim = notesWithoutHtml.Replace("\t", string.Empty);
                    notesWithoutHtmltrim = Regex.Replace(notesWithoutHtmltrim, @"&nbsp;|nbsp|&|&amp;|amp;|#8217;", string.Empty);
                    StringBuilder reviewNote = new StringBuilder();
                    reviewNote.AppendLine();
                    reviewNote.AppendLine();
                    reviewNote.Append(userContext.LastName + ", " + userContext.FirstName + " has added the following note on " + DateTime.Now);
                    reviewNote.AppendLine();
                    reviewNote.Append(notesWithoutHtmltrim);
                    reviewNote.AppendLine();

                    COIUserSummary.SaveCOIReviewNote(coiId, reviewNote.ToString(), DataAccess.ConnectionString);
                    COINote.Visible = existingNote.Visible = viewNote.Visible = addNewNote.Visible = true;
                    saveNote.Visible = newNote.Visible = annunciator.Visible = false;
                    LoadReviewNote();
                }
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        #endregion

        #region private methods

        /// <summary>
        /// Component initialization including event handlers
        /// </summary>
        private void InitializeComponent()
        {
            Load += OnPageLoad;
        }

        /// <summary>
        /// Opens the existing review note as RTF
        /// </summary>
        /// <param name="reviewNote"></param>
        private void OpenReviewNoteAsRTF(string reviewNote)
        {
            try
            {
                Response.Clear();
                Response.ClearHeaders();

                Response.AppendHeader("Content-Disposition",
                    "attachment; filename=\"" + "COI Review Notes.rtf" + "\"");
                Response.ContentType = "application/rtf";
                Response.ContentEncoding = Encoding.UTF8;
                Response.AddHeader("Content-length", Convert.ToString(reviewNote.Length));
                Response.Write(reviewNote);
                Response.Flush();
                Response.End();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Loads the required review note control(s)
        /// </summary>
        private void LoadReviewNote()
        {
            pageCache = pageCachePolicy.GetCachedObject(PageCacheKey) as Hashtable;
            if (!IsPostBack)
            {
                pageCachePolicy.UnCache(PageCacheKey);
                pageCache = null;
                object obj = Request.QueryString["COIId"];
                coiId = (obj != null) ? Convert.ToInt32(obj) : (pageCache != null) ? Convert.ToInt32(pageCache[Keys.COIIdKey]) : 0;
                obj = Request.QueryString["CanAdd"];
                canAdd = (obj != null) ? Convert.ToBoolean(obj) : (pageCache != null) ? Convert.ToBoolean(pageCache[CanAddNoteKey]) : canAdd;
            }
            else
            {
                coiId = (pageCache != null) ? Convert.ToInt32(pageCache[Keys.COIIdKey]) : 0;
                canAdd = (pageCache != null) ? Convert.ToBoolean(pageCache[CanAddNoteKey]) : false;
            }

            if (coiId > 0)
            {
                //The following code will support the display of existing coi notes.
                SqlDataReader COINotesReader = COIUserSummary.GetCOIReviewNote(coiId, DataAccess.ConnectionString);
                if (null != COINotesReader)
                {
                    if (COINotesReader.HasRows)
                    {
                        COINotesReader.Read();
                        COINote.Text = COINotesReader["ReviewNote"].ToString();
                        COINotesReader.Close();
                    }
                    if (COINote.Text == string.Empty)
                    {
                        COINote.Visible = existingNote.Visible = viewNote.Visible = false;
                        annunciator.Title = "No COI review note has been added yet:";
                        annunciator.Message = "To add a note, Click the 'add note' button.";
                    }
                    if (pageCache == null)
                    {
                        pageCache = new Hashtable();
                    }
                    pageCache[Keys.COIIdKey] = coiId;
                    pageCache[CanAddNoteKey] = canAdd;
                    pageCachePolicy.Cache(PageCacheKey, pageCache);
                }
                addNewNote.Visible = canAdd;
            }
        }

        /// <summary>
        /// Displays an error message on the screen to the user with the exception, and all
        /// inner exception messages.
        /// </summary>
        /// <param name="ex">The exception to report on</param>
        private void DisplayExceptionReport(Exception ex)
        {
            annunciator.Title = AnnunciatorTitle;
            annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
        }

        #endregion
    }
}